本篇要來介紹Expo地理位置追蹤套件 - Expo Location
講解在React Native Expo專案怎麼做到
取得位置是非常隱私的項目
在下載其他APP時,不彷查看APP是否使用位置,使用了要做甚麼
是使用一次,還是背景永遠使用
否則APP一直莫名其妙在追蹤你的位置
位置資訊可能已經傳到後台做非法利用了😮
也因為位置是非常隱私,甚至防有心人士追蹤位置的功能
Play 商店 & App Store 在上架審查時
對於位置追蹤審查是非常嚴格的(往往要送上審查說明、Demo影片...等)
先評估開發前要做到哪一項需求
哪種類型的APP只需一次性位置
哪種類型的APP需要背景位置追蹤
官方介紹 & Usage:https://docs.expo.dev/versions/latest/sdk/location/
Expo Location用於地理資訊位置追蹤
可以獲得當前手機位置座標、檢查APP位置權限
該套件還有座標轉地址、電子圍籬、指南針...等地理資訊功能
本篇只介紹GPS位置紀錄部分
npx expo install expo-location
使用版本:16.1.0
只要牽扯隱私權相關,就一定得設定這些隱私權
讓使用者知道你的APP要取得他的位置
否則會觸犯個資法😮
手機定位資訊係屬個人資料保護法第2 條第1 款規定之個人資料,為隱私權保護之 一環
修改app.json
android & ios標籤分別加入權限相關功能
"ios": {
"supportsTablet": true,
"infoPlist": {
"NSLocationUsageDescription": "啟用定位服務 才能使用定位功能",
"NSLocationWhenInUseUsageDescription": "啟用定位服務 才能使用定位功能",
}
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#ffffff"
},
"package": "com.xxxx.expoapp",
"permissions":["ACCESS_COARSE_LOCATION","ACCESS_FINE_LOCATION"]
},
Android權限講解:ACCESS_COARSE_LOCATION
允許應用程式存取大概位置。ACCESS_FINE_LOCATION
允許應用程式存取精確位置。
IOS權限講解:NSLocationUsageDescription
告訴用戶應用程式第一次啟動並請求位置權限時
系統將向用戶顯示此描述NSLocationWhenInUseUsageDescription
告訴用戶應用程式為何僅在使用時需要位置權限時
向用戶解釋原因
引入expo-location
import * as Location from 'expo-location';
檢查前景GPS權限
async function VaildGPSPremission() {
let { status } = await Location.requestForegroundPermissionsAsync();
if (status !== "granted") {
Alert.alert("尚未打開手機GPS定位功能");
return false;
} else {
return true;
}
}
取得一次位置
async function GetLocation() {
try {
let location = await Location.getCurrentPositionAsync({accuracy: Location.Accuracy.Balanced});
return location;
} catch (e) {
console.log(e);
}
}
accuracy
可以調整位置精準度
取得速度會因使用者的GPS訊號、網路速度而改變
要注意的是,越精準速度越慢,反之越快
建議使用Balanced
、High
其他選項不是偏差太多,就是太慢
Accuracy.Lowest
三公里以內Accuracy.Low
一公里以內Accuracy.Balanced
一百米以內Accuracy.High
十米以內Accuracy.Highest
最高精準度Accuracy.BestForNavigation
傳感器準度支援(運動手錶、行車紀錄器)return location
Json格式參考
{
"coords": {
"altitude": 21.195085525512695,
"altitudeAccuracy": 2.2917959690093994,
"latitude": 25.02579835865695,
"accuracy": 35,
"longitude": 121.50828483818138,
"heading": -1,
"speed": -13,
"timestamp": 1658717013053.115
}
}
介紹常用的回傳屬性應用
latitude
緯度longitude
經度heading
方向(0~360)speed
行進速度timestamp
位置取得時間背景位置追蹤功能相對一次性取得位置
困難度會大幅提升
文章篇幅較長還請見諒🥺
Expo專案對於「背景執行功能」有一項限制
TaskManager works out of the box in the Expo Go app on Android, however, on iOS, you'll need to use a development build.
也就是執行APP時
只有在Using development build
預覽模式才能使用Using Expo Go
無法支援背景執行功能
官方只提到IOS不支援Expo Go背景執行
這邊建議Android也使用預覽模式,會比較貼近真實手機運行狀況
尚未安裝Android Studio的話記得先裝:Android Studio官方安裝連結
AVD Manager建置參考Android鐵人:Android Studio - 安卓手機模擬器AVD Manager
expo-task-manager
是一種可以讓你的APP在背景執行工作的套件
即使你螢幕關掉、滑掉,APP還會繼續工作
若想開發定位以外的定時背景服務,需使用Expo BackgroundFetch
安裝指令:npx expo install expo-task-manager
使用版本:11.3.0
參考上方app.json設定方法,額外新增以下權限
background
權限:"permissions":["ACCESS_COARSE_LOCATION","ACCESS_FINE_LOCATION","ACCESS_BACKGROUND_LOCATION"]
UIBackgroundModes
權限:"UIBackgroundModes": ["location", "fetch"]
"NSLocationAlwaysAndWhenInUseUsageDescription": "啟用定位服務 才能使用背景定位功能",
"NSLocationAlwaysUsageDescription": "啟用定位服務 才能使用背景定位功能"
Android背景權限講解
ACCESS_BACKGROUND_LOCATION
應用程式獲得前景位置資訊存取權時,該應用程式也會自動獲得背景位置資訊存取權IOS背景權限講解:
NSLocationAlwaysAndWhenInUseUsageDescription
在應用程式同時需要「永遠」(Always)和「當使用時」(When In Use)位置權限時向用戶解釋原因NSLocationAlwaysUsageDescription
應用程式需要在背景中始終追蹤位置時向用戶解釋原因,這個選項只有「永遠」和「使用一次」。引入位置元件、APP背景工作管理器
import * as TaskManager from "expo-task-manager";
import * as Location from 'expo-location';
定義背景工作名稱
const LOCATION_TRACKING = "location-tracking";
檢查背景GPS權限
async function VaildGPSPremission() {
let { status } = await Location.requestBackgroundPermissionsAsync();
if (status !== "granted") {
Alert.alert("手機GPS背景定位需設定成使用期間或是永遠");
return false;
} else {
return true;
}
}
背景追蹤核心function
程式碼解釋:
先使用TaskManager.defineTask
定義工作內容
而LOCATION_TRACKING
則是工作名稱
通常StartLocationTracking()
則會放在useEffect
裡進行背景觸發
TaskManager.defineTask(LOCATION_TRACKING, async ({ data, error }) => {
if (error) {
console.log("LOCATION_TRACKING task ERROR:", error);
return;
}
if (data) {
const { locations } = data;
let lat = locations[0].coords.latitude;
let long = locations[0].coords.longitude;
console.log(`${new Date(Date.now()).toLocaleString()}: ${lat},${long}`);
} else {
console.log("no gps data");
}
});
async function StartLocationTracking() {
await Location.startLocationUpdatesAsync(LOCATION_TRACKING, {
accuracy: Location.Accuracy.Balanced,
timeInterval: 5000,
deferredUpdatesInterval: 10000,
deferredUpdatesDistance: 0,
distanceInterval: 0,
foregroundService: {
notificationTitle: "GPS",
notificationBody: "body",
notificationColor: "#0000FF",
},
});
const hasStarted = await Location.hasStartedLocationUpdatesAsync(
LOCATION_TRACKING
);
if (hasStarted) {
console.log('Location tracking started:', hasStarted);
}
}
LocationTaskOptions
定期位置追蹤設定講解
accuracy
精準度,可參考上方一次性定位設定timeInterval
位置更新最短時間間隔(毫秒)distanceInterval
移動超過指定距離時,才觸發位置更新(米)deferredUpdatesInterval
延遲位置更新時間間隔(毫秒)deferredUpdatesDistance
延遲移動超過指定距離時,才觸發位置更新(米)foregroundService
在APP通知選單顯示正在被背景追蹤deferred
指的是背景執行時會發生延遲的狀況distance
會回傳比較少的位置,移動距離若不遠則不會回傳多餘資訊
目前使用console.log
追蹤位置data
可自行調整是否要回傳伺服器
或使用useContext
傳遞位置資訊給使用者看
停止背景追蹤function
function StopLocationTracking() {
TaskManager.isTaskRegisteredAsync(LOCATION_TRACKING).then((tracking) => {
if (tracking) {
Location.stopLocationUpdatesAsync(LOCATION_TRACKING);
}
});
}
完整程式碼可參考外國大神針對背景追蹤撰寫的文章:
https://arnav25.medium.com/background-location-tracking-in-react-native-d03bb7652602
npx expo start 主要用於開發過程中的本地預覽和除錯,而 npx expo run:android 用於在 Android 設備或模擬器上運行你的應用程序以進行更全面的測試。這兩個命令通常在不同的階段和用途中使用
啟動指令:npx expo run:android --device
該啟動指令會直接使用development build
模式執行APP--device
參數可以自行選擇設備
該指令像是直接在實體機器/模擬器安裝APP,而不是使用Expo Go執行
真實設備插入Usb進電腦就能使用
啟動背景追蹤前
Android模擬器需先關閉「未使用APP暫停活動」Pause app activity if unused
調整重開APP後在進行背景追蹤
背景追蹤效果如下
Google Pixel XL:
Android版本:13
Iphone 14 Pro Max:
IOS版本:16
可以看到關閉螢幕、關閉APP時
仍在記錄使用者的位置
結語:
位置追蹤功能大概是做專案以來
花最長時間在學習、開發、測試的環節
也從中學習到自己所安裝的APP
是怎麼追蹤位置資訊的
Expo套件介紹系列,到這邊也告一段落了
下一篇要來介紹
Mockapi 後端資料測試前後端串接
讓前端APP能與API溝通並回傳、驗證
隨著鐵人賽文章接近尾聲
下一篇也是最後一篇開發環節了😥。